package co.edu.unal.bioingenium.kbmed.text.representation.io;

import co.edu.unal.bioingenium.kbmed.config.Configuration;
import co.edu.unal.bioingenium.kbmed.text.representation.vo.Corpus;
import co.edu.unal.bioingenium.kbmed.text.representation.vo.Document;
import co.edu.unal.bioingenium.kbmed.util.io.FileManager;
import gnu.trove.map.TObjectIntMap;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Alejandro Riveros Cruz Riveros Cruz
 */
public class CorpusIO {

    public static void storePlainCorpus(Corpus corpus, String name) {
        BufferedWriter bufferedWriter = null;
        try {
            String path = Configuration.EXPERIMENTS_DIR + File.separator + FileManager.getStandardName(name) + "PlainCorpus.txt";
            bufferedWriter = new BufferedWriter(new FileWriter(path));
            bufferedWriter.write("ConstructionDetails: " + corpus.getConstructionDetails() + "\n");
            bufferedWriter.write("TotalDocuments:" + corpus.getTotalDocuments() + "\n");
            bufferedWriter.write("TotalWords:" + corpus.getTotalWords() + "\n");
            bufferedWriter.write("AverageDocumentLength:" + corpus.getAverageDocumentLength() + "\n");
            Map<String, Document> documentCollection = corpus.getDocumentCollection();
            Document tempDocument;
            TObjectIntMap<String> tempWords;
            for (String documentName : documentCollection.keySet()) {
                bufferedWriter.write(documentName + ":");
                tempDocument = documentCollection.get(documentName);
                tempWords = tempDocument.getWordList();
                for (String word : tempWords.keySet()) {
                    bufferedWriter.write("(" + word + "," + tempWords.get(word) + ")");
                }
                bufferedWriter.newLine();
            }
            bufferedWriter.flush();
            bufferedWriter.close();
        } catch (IOException ioex) {
            Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, ioex);
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException ex) {
                Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        try {
            String path = Configuration.EXPERIMENTS_DIR + File.separator + FileManager.getStandardName(name) + "PlainWordList.txt";
            bufferedWriter = new BufferedWriter(new FileWriter(path));
            List<String> sortedWordList = corpus.getSortedWordList();
            bufferedWriter.write("index,word,InObjectOcurrences,TotalOcurrences\n");
            String word;
            for (int i = 0; i < sortedWordList.size(); i++) {
                word = sortedWordList.get(i);
                bufferedWriter.write(i + "," + word + "," + corpus.getDocumentOcurrences(word) + "," + corpus.getWordOcurrences(word) + "\n");
            }
            bufferedWriter.flush();
            bufferedWriter.close();
        } catch (IOException ioex) {
            Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, ioex);
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException ex) {
                Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        try {
            String path = Configuration.EXPERIMENTS_DIR + File.separator + FileManager.getStandardName(name) + "DocumentList.txt";
            bufferedWriter = new BufferedWriter(new FileWriter(path));
            List<String> sortedDocumentList = corpus.getSortedDocumentList();
            bufferedWriter.write("index,documentName\n");
            for (int i = 0; i < sortedDocumentList.size(); i++) {
                bufferedWriter.write(i + "," + sortedDocumentList.get(i) + "\n");
            }
            bufferedWriter.flush();
            bufferedWriter.close();
        } catch (IOException ioex) {
            Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, ioex);
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException ex) {
                Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     *
     *
     * @param corpus
     * @param name 
     */
    public static void storeCorpus(Corpus corpus, String name) {
        FileOutputStream fileOutputStream = null;
        try {
            File file = new File(Configuration.DATA_DIR + File.separator + name);
            if (!file.exists()) {
                file.createNewFile();
            }
            fileOutputStream = new FileOutputStream(file);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            objectOutputStream.writeObject(corpus);
            objectOutputStream.close();
        } catch (IOException ioex) {
            Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, ioex);
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException ex) {
                Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     *
     *
     * @param name 
     * @return
     */
    public static Corpus loadCorpus(String name) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(Configuration.DATA_DIR + File.separator + name);
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            Corpus corpus = (Corpus) objectInputStream.readObject();
            objectInputStream.close();
            return corpus;
        } catch (ClassNotFoundException cnfe) {
            Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, cnfe);
        } catch (IOException ioex) {
            Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, ioex);
        } finally {
            try {
                fileInputStream.close();
            } catch (IOException ex) {
                Logger.getLogger(CorpusIO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }
}
